home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / utilmus / mod2smp.lha / source / mixcli.c < prev    next >
C/C++ Source or Header  |  1996-01-26  |  22KB  |  780 lines

  1. #define MAXIM  0x10000
  2. #define VBLVAL 70938
  3. #define VBLVALNTSC 71591
  4. #define CIAVAL 1773447
  5. #define CIAVALNTSC 1789772
  6.  
  7. #include<stdio.h>
  8. #include<stdlib.h>
  9. #include<proto/exec.h>
  10. #include<exec/memory.h>
  11. #include<proto/dos.h>
  12.  
  13. UBYTE    ver[]="$VER: Mod2Smp V0.78 by Hali of oNION (27/1/96)\0";
  14. UBYTE    help[]="  Module to Sample V0.78    © 1995-96 by Hali of Union\n Here comes short instruction:\n   mod2smp <modulename> <samplename> <pattern>\n        <start> <stop> <volume> <pitch note> [options]\n options:\n   -f??   VBlank speed\n   -c???  CIA speed\n   -n     NTSC\n   -s     Sustain\n   -v     VBlank only\n   -r?    Resampling method (0,1)\n and example:\n   mod2smp \"df0:mod.cipa 6\" ram:kupa 0 0 15 75 C-3 -f3\n If you have any comments or suggestions write to:\n Karol Gozlinski, Stanislawowska 1/24, 05-300 Minsk Maz., Poland\n.\n\0";
  15.  
  16. struct    kupa {                // user interface
  17.     UBYTE    modstrt;
  18.     UBYTE    modstop;
  19.     UBYTE    speed;
  20.     UBYTE    patt;
  21.     WORD    destperd;
  22.     UBYTE    volume;
  23.     UBYTE    ciaspeed;
  24.     UBYTE    ciaon;
  25.     UBYTE    ntscon;
  26.     UBYTE    resampling;
  27.     UBYTE    sustain;
  28.     };
  29. struct  sampel {            // opis sampla
  30.     UBYTE    volume;
  31.     BYTE    *smpstrt;
  32.     UWORD    smpstop;
  33.     UWORD    repeat;
  34.     UWORD    repeatlen;
  35.     BYTE    finetune;
  36.     };
  37.  
  38. WORD  periodtab[16][12*3]={
  39.     { 856,808,762,720,678,640,604,570,538,508,480,453,    // Tuning 0, Normal
  40.       428,404,381,360,339,320,302,285,269,254,240,226,
  41.       214,202,190,180,170,160,151,143,135,127,120,113},
  42.     { 850,802,757,715,674,637,601,567,535,505,477,450,    // Tuning 1
  43.       425,401,379,357,337,318,300,284,268,253,239,225,
  44.       213,201,189,179,169,159,150,142,134,126,119,113},
  45.     { 844,796,752,709,670,632,597,563,532,502,474,447,    // Tuning 2
  46.       422,398,376,355,335,316,298,282,266,251,237,224,
  47.       211,199,188,177,167,158,149,141,133,125,118,112},
  48.     { 838,791,746,704,665,628,592,559,528,498,470,444,    // Tuning 3
  49.       419,395,373,352,332,314,296,280,264,249,235,222,
  50.       209,198,187,176,166,157,148,140,132,125,118,111},
  51.     { 832,785,741,699,660,623,588,555,524,495,467,441,    // Tuning 4
  52.       416,392,370,350,330,312,294,278,262,247,233,220,
  53.       208,196,185,175,165,156,147,139,131,124,117,110},
  54.     { 826,779,736,694,655,619,584,551,520,491,463,437,    // Tuning 5
  55.       413,390,368,347,328,309,292,276,260,245,232,219,
  56.       206,195,184,174,164,155,146,138,130,123,116,109},
  57.     { 820,774,730,689,651,614,580,547,516,487,460,434,    // Tuning 6
  58.       410,387,365,345,325,307,290,274,258,244,230,217,
  59.       205,193,183,172,163,154,145,137,129,122,115,109},
  60.     { 814,768,725,684,646,610,575,543,513,484,457,431,    // Tuning 7
  61.       407,384,363,342,323,305,288,272,256,242,228,216,
  62.       204,192,181,171,161,152,144,136,128,121,114,108},
  63.     { 907,856,808,762,720,678,640,604,570,538,508,480,    // Tuning -8
  64.       453,428,404,381,360,339,320,302,285,269,254,240,
  65.       226,214,202,190,180,170,160,151,143,135,127,120},
  66.     { 900,850,802,757,715,675,636,601,567,535,505,477,    // Tuning -7
  67.       450,425,401,379,357,337,318,300,284,268,253,238,
  68.       225,212,200,189,179,169,159,150,142,134,126,119},
  69.     { 894,844,796,752,709,670,632,597,563,532,502,474,    // Tuning -6
  70.       447,422,398,376,355,335,316,298,282,266,251,237,
  71.       223,211,199,188,177,167,158,149,141,133,125,118},
  72.     { 887,838,791,746,704,665,628,592,559,528,498,470,    // Tuning -5
  73.       444,419,395,373,352,332,314,296,280,264,249,235,
  74.       222,209,198,187,176,166,157,148,140,132,125,118},
  75.     { 881,832,785,741,699,660,623,588,555,524,494,467,    // Tuning -4
  76.       441,416,392,370,350,330,312,294,278,262,247,233,
  77.       220,208,196,185,175,165,156,147,139,131,123,117},
  78.     { 875,826,779,736,694,655,619,584,551,520,491,463,    // Tuning -3
  79.       437,413,390,368,347,328,309,292,276,260,245,232,
  80.       219,206,195,184,174,164,155,146,138,130,123,116},
  81.     { 868,820,774,730,689,651,614,580,547,516,487,460,    // Tuning -2
  82.       434,410,387,365,345,325,307,290,274,258,244,230,
  83.       217,205,193,183,172,163,154,145,137,129,122,115},
  84.     { 862,814,768,725,684,646,610,575,543,513,484,457,    // Tuning -1
  85.       431,407,384,363,342,323,305,288,272,256,242,228,
  86.       216,203,192,181,171,161,152,144,136,128,121,114}};
  87.  
  88. APTR    modptr=0;    // miejsce modulu
  89. APTR    smpptr=0;    // miejsce sampla
  90.  
  91. BYTE    debug=0;
  92.  
  93. // prototypy
  94. ULONG    mixer(struct kupa);
  95. ULONG    mixit(struct kupa);
  96. void    savesample(ULONG,char *);
  97. ULONG    loadmodule(char *);
  98. UWORD    policzpatterny(BYTE *);
  99. void    adresysampli(BYTE *,struct sampel *,UWORD);
  100. WORD    findnote(char *,WORD);
  101. WORD    calculate_pom(WORD,WORD,ULONG,ULONG,UBYTE);
  102. WORD    findperiod(WORD,BYTE,BYTE);
  103.  
  104. ULONG    mixit(sinfo)
  105. struct    kupa sinfo;
  106. {
  107.     if(modptr){
  108.       if(smpptr=AllocMem(MAXIM*2,MEMF_CLEAR|MEMF_PUBLIC)){
  109.         return(mixer(sinfo));
  110.       }
  111.       else{
  112.         printf(" Sorry, not enough memory to allocate sample buffor. \n");
  113.         return(0);
  114.       }
  115.     }
  116.     else{
  117.       printf(" You have to load module first.\n");
  118.       return(0);
  119.     }
  120. }
  121.  
  122. void    savesample(smplen,smpname)
  123. ULONG    smplen;
  124. char    *smpname;
  125. {
  126.     ULONG    smphandle=0;
  127.  
  128.     if(smplen){
  129.       if(smphandle=Open(smpname,MODE_NEWFILE)){
  130.         if( Write(smphandle,smpptr,smplen)!=-1){
  131.           Close(smphandle);
  132.           smphandle=0;
  133.         }
  134.         else{
  135.           printf(" Sorry, I can't save file. \n");
  136.         }
  137.       }
  138.       else{
  139.         printf(" Sorry, I can't open file to save. \n");
  140.       }
  141.     }
  142.     else{
  143.     printf(" Nothing to save.\n");
  144.     }
  145. }
  146.  
  147. ULONG    loadmodule(modname)
  148. char    *modname;
  149. {
  150.     ULONG    modhandle=0;
  151.     ULONG    modlen=0;
  152.  
  153.     if(modhandle=Open(modname,MODE_OLDFILE)){
  154.       modlen=Seek(modhandle,0,OFFSET_END);
  155.       modlen=Seek(modhandle,0,OFFSET_BEGINNING);
  156.       if(modptr=AllocMem(modlen,MEMF_PUBLIC)){
  157.         Read(modhandle,modptr,modlen);
  158.         Close(modhandle);
  159.         modhandle=0;
  160.         if(debug){
  161.           printf(" Module length : %i\n",modlen);
  162.           printf(" Module name   : %s\n",modptr);
  163.           printf(" Module mark   : %4s\n",(ULONG)modptr+1080);
  164.         }
  165.         if( *((ULONG *)((ULONG)modptr+1080))!=*((ULONG *)"M.K.") ){
  166.           printf(" Sorry, this is not a module. \n ");
  167.           FreeMem(modptr,modlen);
  168.           modptr=0;
  169.           modlen=0;
  170.         }
  171.       }
  172.       else{
  173.         printf(" Sorry, not enough memory to load module. \n");
  174.         Close(modhandle);
  175.         modhandle=0;
  176.       }
  177.     }
  178.     else{
  179.       printf(" Sorry, I can't find this module. \n");
  180.     }
  181.     return(modlen);
  182. }    
  183.  
  184.  
  185. main(argc, argv)
  186. int     argc;
  187. char    *argv[];
  188. {
  189.     ULONG    modlen=0,smplen=0;
  190.     struct    kupa sinfo={0,16,6,0,214,75,125,1,0,0,0};
  191.     char     *modname,*smpname;
  192.  
  193.     char opts[] = "gx";    // do opcji
  194.     char option,*odata;
  195.     int next;
  196.  
  197.     if(argc>=8){
  198.       modname=argv[1];
  199.       smpname=argv[2];
  200.       sinfo.patt=atoi(argv[3]);
  201.       sinfo.modstrt=atoi(argv[4]);
  202.       sinfo.modstop=atoi(argv[5]);
  203.       sinfo.volume=atoi(argv[6]);
  204.       sinfo.destperd=findnote(argv[7],0);
  205.  
  206.     // anti-lame
  207.     if(sinfo.modstrt>63) sinfo.modstrt=63;
  208.     if(sinfo.modstop>63) sinfo.modstop=63;
  209.     if(sinfo.modstrt>=sinfo.modstop){
  210.       printf("  I won't play in backward mode.\n");
  211.       goto end;
  212.     }
  213.  
  214.  
  215.       next = 8;
  216.       while((odata = argopt(argc,argv,opts,&next,&option)) != NULL){
  217.         switch(option){
  218.           case 'c':
  219.             sinfo.ciaon=1;
  220.             sinfo.ciaspeed=atoi(odata);
  221.             break;
  222.           case 'f':
  223.             sinfo.speed=atoi(odata);
  224.             break;
  225.           case 'n':
  226.             sinfo.ntscon=1;
  227.             break;
  228.           case 's':
  229.             sinfo.sustain=1;
  230.             break;
  231.           case 'd':
  232.             debug=1;
  233.             break;
  234.           case 'v':
  235.             sinfo.ciaon=0;
  236.             break;
  237.           case 'r':
  238.             sinfo.resampling=atoi(odata);
  239.             break;
  240.         }
  241.       }
  242.  
  243.       modlen=loadmodule(modname);
  244.       if(modlen){
  245.         smplen=mixit(sinfo);
  246.         if(smplen){
  247.           savesample(smplen,smpname);
  248.         }
  249.       }
  250.     }
  251.     else
  252.       printf((char*)help);
  253.  
  254. end:
  255.     if(smpptr)        FreeMem(smpptr,MAXIM*2);
  256.     if(modptr)        FreeMem(modptr,modlen);
  257.     exit(0);
  258. }
  259.  
  260.  
  261. WORD    findnote(note,fine)
  262. char    *note;
  263. WORD    fine;
  264. {
  265.     UWORD    index=0;
  266.     UBYTE    nutka=0;
  267.  
  268. //    printf(note);
  269.     nutka=*note;
  270.     switch(nutka){
  271.       case 'C':
  272.         index=0;
  273.         break;
  274.       case 'D':
  275.         index=2;
  276.         break;
  277.       case 'E':
  278.         index=4;
  279.         break;
  280.       case 'F':
  281.         index=5;
  282.         break;
  283.       case 'G':
  284.         index=7;
  285.         break;
  286.       case 'A':
  287.         index=9;
  288.         break;
  289.       case 'B':
  290.         index=11;
  291.         break;
  292.     };
  293.     if( *(note+1)=='#') index++;
  294.     index=index+((atoi(note+2)-1)*12);
  295.     if(index>12*3) index=12*2;        //anti-lame
  296.     return(periodtab[fine][index]);
  297. }
  298.  
  299. /**********************************\
  300. *                                  *
  301. *               Mixer              *
  302. *                                  *
  303. \**********************************/
  304.  
  305. /*    analiza pozycji
  306.     Info for each note:
  307.     
  308.      _____byte 1_____   byte2_    _____byte 3_____   byte4_
  309.     /                \ /      \  /                \ /      \
  310.     0000          0000-00000000  0000          0000-00000000
  311.     
  312.     Upper four    12 bits for    Lower four    Effect command.
  313.     bits of sam-  note period.   bits of sam-
  314.     ple number.                  ple number.
  315. */
  316.  
  317. #define    FIND_ANYTHING(ptr)  (*((ULONG *)(ptr)))
  318. #define    FIND_PERIOD(ptr)    (*((WORD *)ptr)&0x0fff)
  319. #define    FIND_SMPNUMBER(ptr) (((*ptr)&(0xf0))+((*(ptr+2))>>4))
  320. #define    FIND_EFFECT(ptr)    ((*(ptr+2))&0x0f)
  321. #define    FIND_PARAMETR(ptr)  (*(ptr+3))
  322.  
  323.  
  324. ULONG    mixer(sinfo)
  325. struct    kupa sinfo;
  326. {
  327.     BYTE    *module;            // adres moduîu
  328.     WORD    *fromword;          // pointery do zamiany z word'ow na
  329.     BYTE    *tobyte;            // bajty
  330.     ULONG    len;                // koncowa dlugosc sampla
  331.     ULONG    h,i,j,k;            // zmienne do organizacji petli
  332.     UWORD    hipatt=0;           // tu bedzie ilosc pattern'ów
  333.     ULONG    ilenapoz;           // ile sampla wygenerowac
  334.                                 // do nastepnej pozycji
  335.     WORD    *ptr2smp;           // pointery do generowania
  336.     WORD    *ptr2smppom;        // zmiksowanego sampla ( w word'ach)
  337.     UBYTE    *ptr2mod;           // pointer do przesuwania sie 
  338.                                 // po module
  339.     UBYTE    speed;              // aktualna predkosc
  340.     UBYTE    ciaspeed;
  341.     UBYTE    ilepozycji;         // ile pozycji do zrobienia
  342.     UWORD    pomoc;
  343.     WORD    pom;
  344.     WORD    probka0,probka1;
  345.     UBYTE    sust;
  346.  
  347.     struct    sampel smp[32];     // tablica pointerow do sampli 
  348.     struct    canal {             // co sie dzieje w kanale
  349.         BYTE    nrsmp;       // numer odgrywanego sampla
  350.         BYTE    volume;      // gîoônoôê sampla
  351.         WORD    period;      // period
  352.         ULONG    jump;
  353.         ULONG    jumppos;
  354.         UWORD    smppos;
  355.         BYTE    *smpstrt;
  356.         UWORD    smpstop;
  357.         UWORD    smprepeat;
  358.         UWORD    smprepeatlen;
  359.         BYTE    volslide;    // do komendy - Axx
  360.         UBYTE    last9;       // do komendy - 9xx
  361.         UBYTE    actE9;       // do komendy - E9x
  362.         UBYTE    notecut;     // do komendy - ECx
  363.         WORD    trgetperd;   // do komendy - 3xx
  364.         WORD    toneslide;   // ----------------
  365.         WORD    lasttrget;   // ----------------
  366.         WORD    lasttonesl;  // ----------------
  367.         UBYTE    arpeggio;    // do komendy - 0xx
  368.         WORD    saveperd;    // ----------------
  369.         };
  370.     struct    canal chan[4]={{0,0,0,0,0,0,0,0},
  371.                            {0,0,0,0,0,0,0,0},
  372.                            {0,0,0,0,0,0,0,0},
  373.                            {0,0,0,0,0,0,0,0}};
  374.     struct    line {
  375.         ULONG    anything;
  376.         WORD    period;
  377.         UBYTE    smpnumber;
  378.         UBYTE    effect;
  379.         UBYTE    parametr;
  380.     };
  381.     struct    line    trackline[4];
  382.  
  383.  
  384.     sust=sinfo.sustain;
  385.     module=modptr;
  386.     ptr2smp=smpptr;
  387.     hipatt=policzpatterny(module);
  388.     adresysampli(module,smp,hipatt);
  389.     speed=sinfo.speed;
  390.     ciaspeed=sinfo.ciaspeed;
  391.     if(sust){
  392.       ilepozycji=sinfo.modstop+1;
  393.       ptr2mod=module+1084+1024*sinfo.patt; // ustawienie sie na odpowiednia pozycje
  394.     }
  395.     else{
  396.       ilepozycji=sinfo.modstop-sinfo.modstrt+1;
  397.       ptr2mod=module+1084+1024*sinfo.patt+16*sinfo.modstrt; // ustawienie sie na odpowiednia pozycje
  398.     }
  399.  
  400.     if(debug)  printf("   Destination Period = %i\n",sinfo.destperd);
  401.  
  402.  
  403.     printf("   Wow! There will be %i positions. \n    >",ilepozycji);
  404.     for(h=0;h<=(ilepozycji-1);h++){
  405.  
  406.       if((sust)&&(h>=sinfo.modstrt)) sust=0;
  407.  
  408.       for(i=0;i<=3;i++){
  409.         trackline[i].anything  = (ULONG)FIND_ANYTHING(ptr2mod);
  410.         trackline[i].period    = (WORD)FIND_PERIOD(ptr2mod);
  411.         trackline[i].smpnumber = (UBYTE)FIND_SMPNUMBER(ptr2mod);
  412.         trackline[i].effect    = (UBYTE)FIND_EFFECT(ptr2mod);
  413.         trackline[i].parametr  = (UBYTE)FIND_PARAMETR(ptr2mod);
  414.         ptr2mod=ptr2mod+4;
  415.       }
  416.  
  417.       if(debug){
  418.         printf("\n"); 
  419.         for(i=0;i<=3;i++){
  420.           if(trackline[i].period) printf("  J-4");
  421.           else printf("  ---");
  422.           printf("%2x%1x%2x",trackline[i].smpnumber,trackline[i].effect,trackline[i].parametr);
  423.         }
  424.       }
  425.  
  426.  
  427.  
  428.  
  429.       for(i=0;i<=3;i++){
  430.         chan[i].volslide=0;
  431.         chan[i].actE9=0;
  432.         chan[i].toneslide=0;
  433.         chan[i].arpeggio=0;
  434.         chan[i].saveperd=0;
  435.         if(trackline[i].smpnumber){
  436.            chan[i].nrsmp=trackline[i].smpnumber;
  437.           chan[i].volume=smp[chan[i].nrsmp].volume;
  438.         }
  439.         pomoc=0;
  440.         if(trackline[i].effect==0x03) pomoc=1;
  441.         if(trackline[i].effect==0x05) pomoc=1;
  442.         if( (trackline[i].period)&&(pomoc==0) ){
  443.           chan[i].period=trackline[i].period;
  444.           chan[i].trgetperd=0;
  445.           if( smp[chan[i].nrsmp].finetune)
  446.             chan[i].period = findperiod( chan[i].period, smp[chan[i].nrsmp].finetune,0);
  447.           chan[i].smpstrt=smp[chan[i].nrsmp].smpstrt;
  448.           chan[i].smpstop=smp[chan[i].nrsmp].smpstop;
  449.           chan[i].smprepeat=smp[chan[i].nrsmp].repeat;
  450.           chan[i].smprepeatlen=smp[chan[i].nrsmp].repeatlen;
  451.           chan[i].smppos=0;
  452.           chan[i].jumppos=0;
  453.         }
  454.         switch(trackline[i].effect){
  455.           case 0x0f:
  456.             if( (sinfo.ciaon)&&(trackline[i].parametr>0x1f) )
  457.               ciaspeed=trackline[i].parametr;
  458.             else
  459.               speed=trackline[i].parametr;
  460.             break;
  461.           case 0x0e:
  462.             switch(trackline[i].parametr>>4){
  463.               case 0x09:
  464.                 chan[i].actE9=trackline[i].parametr&0x0f;
  465.               break;
  466.               case 0x0a:
  467.                 chan[i].volume+=trackline[i].parametr&0x0f;
  468.               break;
  469.               case 0x0b:
  470.                 chan[i].volume-=trackline[i].parametr&0x0f;
  471.               break;
  472.               case 0x0c:
  473.                 chan[i].notecut=(trackline[i].parametr&0x0f)+1;
  474.               break;
  475.               case 0x02:
  476.                 chan[i].period+=trackline[i].parametr&0x0f;
  477.                 if( chan[i].period>findperiod(856,smp[chan[i].nrsmp].finetune,0) )
  478.                   chan[i].period=findperiod(856,smp[chan[i].nrsmp].finetune,0);
  479.               break;
  480.               case 0x01:
  481.                 chan[i].period-=trackline[i].parametr&0x0f;
  482.                 if( chan[i].period<findperiod(113,smp[chan[i].nrsmp].finetune,0) )
  483.                   chan[i].period=findperiod(113,smp[chan[i].nrsmp].finetune,0);
  484.               break;
  485.             }
  486.             break;
  487.           case 0x0c:
  488.             chan[i].volume=trackline[i].parametr;
  489.             break;
  490.           case 0x0a:
  491.             if( (trackline[i].parametr)&0xf0)
  492.               chan[i].volslide=(trackline[i].parametr>>4)&0x0f;
  493.             else
  494.               chan[i].volslide=-trackline[i].parametr;
  495.             break;
  496.           case 0x09:
  497.             if(trackline[i].parametr)
  498.               chan[i].last9=trackline[i].parametr;
  499.             pomoc=((UWORD)chan[i].last9)<<8;
  500.             if(pomoc>(chan[i].smpstop))
  501.               chan[i].smppos=chan[i].smprepeat;
  502.             else
  503.               chan[i].smppos=pomoc;
  504.             chan[i].jumppos=0;
  505.             break;
  506.           case 0x05:
  507.             if( (trackline[i].parametr)&0xf0)
  508.               chan[i].volslide=(trackline[i].parametr>>4)&0x0f;
  509.             else
  510.               chan[i].volslide=-trackline[i].parametr;
  511.             if(trackline[i].period){
  512.               chan[i].trgetperd=findperiod(trackline[i].period,smp[chan[i].nrsmp].finetune,0);
  513.               chan[i].lasttrget=chan[i].trgetperd;
  514.             }
  515.             else{
  516.               chan[i].trgetperd=chan[i].lasttrget;
  517.             }
  518.             if( chan[i].period>chan[i].trgetperd )
  519.               chan[i].toneslide=-chan[i].lasttonesl;
  520.             else
  521.               chan[i].toneslide=chan[i].lasttonesl;
  522.             if(chan[i].trgetperd==0) chan[i].toneslide=0;
  523.             break;
  524.           case 0x03:
  525.             if(trackline[i].period){
  526.               chan[i].trgetperd=findperiod(trackline[i].period,smp[chan[i].nrsmp].finetune,0);
  527.               chan[i].lasttrget=chan[i].trgetperd;
  528.             }
  529.             else{
  530.               chan[i].trgetperd=chan[i].lasttrget;
  531.             }
  532.             chan[i].lasttonesl=trackline[i].parametr;
  533.             if( chan[i].period>chan[i].trgetperd )
  534.               chan[i].toneslide=-trackline[i].parametr;
  535.             else
  536.               chan[i].toneslide=trackline[i].parametr;
  537.             if(chan[i].trgetperd==0) chan[i].toneslide=0;
  538.             break;
  539.           case 0x02:
  540.             chan[i].trgetperd=findperiod(856,smp[chan[i].nrsmp].finetune,0);
  541.             chan[i].toneslide=trackline[i].parametr;
  542.             break;
  543.           case 0x01:
  544.             chan[i].trgetperd=findperiod(113,smp[chan[i].nrsmp].finetune,0);
  545.             chan[i].toneslide=-trackline[i].parametr;
  546.             break;
  547.           case 0x00:
  548.             if(trackline[i].parametr){
  549.               chan[i].arpeggio=trackline[i].parametr;
  550.               chan[i].saveperd=chan[i].period;
  551.             }
  552.             break;
  553.         } 
  554.       }
  555.  
  556.       // ile probek
  557.       if(sinfo.ciaon){
  558.         if(sinfo.ntscon)
  559.           ilenapoz=((CIAVALNTSC*5)/ciaspeed)/sinfo.destperd;
  560.         else
  561.           ilenapoz=((CIAVAL*5)/ciaspeed)/sinfo.destperd;
  562.       }
  563.       else{  
  564.         if(sinfo.ntscon)
  565.           ilenapoz=VBLVALNTSC/sinfo.destperd;
  566.         else
  567.           ilenapoz=VBLVAL/sinfo.destperd;
  568.       }
  569.  
  570.       // mixowanie
  571.       for(i=0;i<=3;i++){
  572.       ptr2smppom=ptr2smp;
  573.       //printf("\n");
  574.         for(k=0;k<=(speed-1);k++){
  575.           // comman E9x retrig note
  576.           if(chan[i].actE9){
  577.             if( (k-(k/chan[i].actE9)*chan[i].actE9)==0 ){
  578.               chan[i].smppos=0;
  579.               chan[i].jumppos=0;
  580.               chan[i].smpstop=smp[chan[i].nrsmp].smpstop;
  581.             }
  582.           }
  583.           // comman ECx note cut
  584.           if(chan[i].notecut){
  585.             if( k==(chan[i].notecut-1) ){
  586.               chan[i].volume=0;
  587.             }
  588.           }
  589.           // command Axx volsliding
  590.           if((chan[i].volslide)&&(k!=0)){
  591.             chan[i].volume=chan[i].volume+chan[i].volslide;
  592.             if(chan[i].volume<0) chan[i].volume=0;
  593.             if(chan[i].volume>64) chan[i].volume=64;
  594.           }
  595.           // command 3xx tone sliding
  596.           if((chan[i].toneslide)&&(k!=0)){
  597.             //printf("!");
  598.             chan[i].period+=chan[i].toneslide;
  599.             if(chan[i].toneslide<0){
  600.               if(chan[i].period<chan[i].trgetperd)
  601.                 chan[i].period=chan[i].trgetperd;
  602.             }
  603.             else{
  604.               if(chan[i].period>chan[i].trgetperd)
  605.                 chan[i].period=chan[i].trgetperd;
  606.             }
  607.           }
  608.           // command 0xx arpeggio
  609.           if(chan[i].arpeggio){
  610.                 switch( k-(k/3)*3 ){
  611.               case 2:
  612.                 chan[i].period=findperiod( chan[i].saveperd, smp[chan[i].nrsmp].finetune, chan[i].arpeggio&0x0f);
  613.                 break;
  614.               case 1:
  615.                 chan[i].period=findperiod( chan[i].saveperd, smp[chan[i].nrsmp].finetune, chan[i].arpeggio>>4);
  616.                 break;
  617.               case 0:
  618.                 chan[i].period=chan[i].saveperd;
  619.                 break;
  620.             }
  621.           }
  622.  
  623.           //printf(" %i",chan[i].period);
  624.  
  625.           if(chan[i].period!=0)
  626.             chan[i].jump=(((ULONG)sinfo.destperd)<<16)/chan[i].period;
  627.           else
  628.             chan[i].jump=0;
  629.  
  630.           // generowanie sampla
  631.           for(j=0;j<=ilenapoz;j++){
  632.             if((ULONG)ptr2smppom>=(ULONG)smpptr+MAXIM*2) break; // jesli przekroczymy bufor to stop
  633.  
  634.             chan[i].smppos+=(UWORD)(chan[i].jumppos>>16);
  635.             chan[i].jumppos=chan[i].jumppos&0xffff;
  636.  
  637.             if(chan[i].smppos>=chan[i].smpstop){
  638.                chan[i].smppos=chan[i].smprepeat+(chan[i].smppos-chan[i].smpstop);
  639.                chan[i].smpstop=chan[i].smprepeat+chan[i].smprepeatlen;
  640.             }
  641.  
  642.             probka0=*(chan[i].smppos+chan[i].smpstrt);
  643.             probka1=*(chan[i].smppos+chan[i].smpstrt+1);
  644.             if((chan[i].smppos+1)>=chan[i].smpstop){
  645.                 probka1=*(chan[i].smprepeat+chan[i].smpstrt);
  646.             }
  647.  
  648.             pom=calculate_pom(probka0,probka1,chan[i].jumppos,chan[i].jump,sinfo.resampling);
  649.  
  650.             if(sust==0){
  651.               *ptr2smppom+=(pom*chan[i].volume)/64;
  652.               ptr2smppom++;
  653.             }
  654.             chan[i].jumppos+=chan[i].jump;
  655.           }
  656.         }
  657.         if(chan[i].saveperd){
  658.           chan[i].period=chan[i].saveperd;
  659.         }
  660.       }
  661.       ptr2smp=ptr2smppom;
  662.       printf("*");
  663.     }
  664.     printf("\n");
  665.  
  666.     // obcinanie
  667.     len=((ULONG)ptr2smp-(ULONG)smpptr)/2;
  668.     fromword=smpptr;
  669.     tobyte=smpptr;
  670.     for(i=0;i<=len;i++){
  671.       pom=((*fromword++)*sinfo.volume)/100;
  672.       if(pom>127) pom=127;
  673.       if(pom<-128) pom=-128;
  674.       *tobyte++=pom;
  675.       if((i>>10)<<10==i)
  676.         printf("\r   hmm ... : %i ",i);
  677.     }
  678.     printf("\r   OK it's: %i \n",i);
  679.  
  680.     return(len);
  681. }
  682.  
  683. WORD    findperiod(mainperiod,finetune,index)
  684. WORD    mainperiod;
  685. BYTE    finetune;
  686. BYTE    index;
  687. {
  688.     UWORD    i;
  689.  
  690.     for(i=0;i<=12*3;i++)
  691.       if(mainperiod==periodtab[0][i]) break;
  692.     i=i+index;
  693.     if(i>=12*3) return(0);
  694.  
  695.     return(periodtab[finetune][i]);
  696. }
  697.  
  698. WORD    calculate_pom(sample0,sample1,jumppos,jump,method)
  699. WORD    sample0;
  700. WORD    sample1;
  701. ULONG    jumppos;
  702. ULONG    jump;
  703. UBYTE    method;
  704. {
  705.     WORD    a;
  706.     WORD    i;
  707.     ULONG    myjumppos;
  708.  
  709.     if(jump==0) return(0);
  710.  
  711.     myjumppos=jumppos;
  712.  
  713.     if(method){
  714.       for(i=1;(jump)<(0x10000/(i+1));i++);
  715.       //printf("i= %i\n",i);
  716.       if(i>1){
  717.         if(jumppos<((0x10000/i)*(i-1)))
  718.           return(sample0);
  719.         else{
  720.           myjumppos=(jumppos-((0x10000/i)*(i-1)))*i;
  721.         }
  722.       }
  723.     }
  724.  
  725.     a=sample1-sample0;
  726.     a=(WORD)(((LONG)myjumppos*a)>>16);
  727.     a=a+sample0;
  728.     return(a);
  729. }
  730.  
  731.  
  732. UWORD    policzpatterny(module)
  733. BYTE    *module;
  734. {
  735.     UWORD    pomoc;
  736.     UWORD    i;
  737.     UWORD    hipat=0;
  738.  
  739.     for(i=0;i<=127;i++){
  740.       pomoc=*((UBYTE *)(module+952+i));
  741.       hipat=(hipat>pomoc)?hipat:pomoc;
  742.     }
  743.     hipat++;
  744.     return(hipat);
  745. }
  746.  
  747.  
  748.  
  749. void    adresysampli(module,smp,hipatt)
  750. BYTE    *module;
  751. struct    sampel smp[];        // tablica pointerow do sampli 
  752. UWORD    hipatt;
  753. {
  754.     UWORD    i;
  755.     UWORD    pomoc;
  756.  
  757.     smp[1].smpstrt=module+1084+1024*hipatt;
  758.     smp[1].smpstop=(*((UWORD *)(module+42)))*2;
  759.     smp[1].volume=*((UBYTE *)(module+45));
  760.     smp[1].repeat=(*((UWORD *)(module+46)))*2;
  761.     smp[1].repeatlen=(*((UWORD *)(module+48)))*2;
  762.     smp[1].finetune=*((UBYTE *)(module+44));
  763.     for(i=2;i<=31;i++){
  764.       pomoc=*((UWORD *)(module+42+30*(i-2)));
  765.       smp[i].smpstrt=smp[i-1].smpstrt+pomoc*2;
  766.       smp[i].smpstop=(*((UWORD *)(module+42+30*(i-1))))*2;
  767.       smp[i].volume=*((UBYTE *)(module+45+30*(i-1)));
  768.       smp[i].repeat=(*((UWORD *)(module+46+30*(i-1))))*2;
  769.       smp[i].repeatlen=(*((UWORD *)(module+48+30*(i-1))))*2;
  770.       smp[i].finetune=*((UBYTE *)(module+44+30*(i-1)));
  771.       if(smp[i].repeat)  smp[i].smpstop=smp[i].repeat+smp[i].repeatlen;
  772.     }
  773.  
  774.     if(debug){
  775.       for(i=1;i<=8;i++)
  776.         printf("%2i vol %-2x strt $%-6x stop $%-4x %-5irepeat $%-4xrepeatlen $%-4xfinetune %1i\n",i,smp[i].volume,smp[i].smpstrt,smp[i].smpstop,smp[i].smpstop,smp[i].repeat,smp[i].repeatlen,smp[i].finetune);
  777.     }
  778. }
  779.  
  780.